﻿Imports DotNetNuke.Entities.Modules
Imports Aricie.ComponentModel
Imports Aricie.DNN.Modules.LuceneSearch.Business
Imports System.Data
Imports LSCommon = Aricie.DNN.Modules.LuceneSearch.Common
Imports Aricie.DNN.Modules.LuceneSearch.Settings
Imports Aricie.DNN.Settings
Imports DotNetNuke.Services.Localization
Imports DotNetNuke.Services.Exceptions
Imports Aricie.DNN.Modules.LuceneSearch.UI.Controls

Namespace Aricie.DNN.Modules.LuceneSearch.UI
    Partial Public Class GridViewResultsControl
        Inherits LuceneResultsControlBase




        Private Const glbWithoutLink As String = "WithoutLink"


#Region " Event Handlers"

        Protected Overrides Sub OnInit(e As System.EventArgs)

            ' je suis obligé de faire ça ici car l'en-tête n'apparait que s'il y a une ligne de données
            ' comme je dois rebinder les évèntements des flèches de tri je fais un bind explicite d'une ligne de données
            ' mais je cache le résultat, la grille sera visible plus tard si une véritable recherche est lancée

            Dim data = GenerateDataSource(New List(Of LuceneSearchResultsInfo), True, SearchQuery, String.Empty)
            data.AddNew()
            gridViewAllResults.DataSource = data
            gridViewAllResults.DataBind()
            gridViewAllResults.Visible = False



            MyBase.OnInit(e)
        End Sub

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not Page.IsPostBack Then
                InitQuery()
                InitLayout()
            End If

            'Nécessaire au fonctionnement du pager lorsqu'ajax n'est pas activé.
            ' on affiche le pager si on est en mode printing mais que 
            Dim ShouldDisplayPagerWhenPrinting As Boolean = Not Me.Request.Params(LSCommon.Constants.UrlParameters.LuceneSearchModeParameter) = LSCommon.Constants.UrlParameters.PrintMode _
                                                            OrElse Not LuceneResultsSettings.DisablePagingForPrint

            If Me.phPager.Controls.Count = 0 AndAlso NbResults > 0 AndAlso ShouldDisplayPagerWhenPrinting Then
                AddPager(NbResults)
            End If
        End Sub


        Public Overrides Sub DisplayResults(ByVal resultsList As System.Collections.Generic.IList(Of Business.LuceneSearchResultsInfo), ByVal nbResultFound As Integer, ByVal sortFieldName As String, ByVal printMode As Boolean, Optional ByVal pageIndex As Integer = -1)
            gridViewAllResults.DataSource = GenerateDataSource(resultsList, True, Me.SearchQuery, GetSortParameter())

            If pageIndex <> -1 Then
                Me.PageIndex = pageIndex
            End If

            gridViewAllResults.PageIndex = Me.PageIndex
            gridViewAllResults.PagerSettings.Visible = False
            
            InitLayout() ' bizarre, pourquoi le faire ici... pourquoi le load est-il effectué après l'appel au niveau supérieur...?

            If Me.LuceneResultsSettings.DisablePagingForPrint AndAlso printMode Then
                Me.gridViewAllResults.AllowPaging = False
                Me.phPager.Visible = False
                Me.gridViewAllResults.DataBind()
            Else
                Me.gridViewAllResults.DataBind()
                AddPager(nbResultFound)
            End If

            NbResults = nbResultFound

            gridViewAllResults.Visible = True
        End Sub



        Private Sub ddlCustomPageSize_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlCustomPageSize.SelectedIndexChanged
            Dim strPageSize As String = Me.ddlCustomPageSize.SelectedValue
            Dim intPageSize As Integer
            If strPageSize = "Default" Then
                strPageSize = Me.LuceneResultsSettings.DefaultPageSize.ToString
            End If
            intPageSize = CInt(strPageSize)

            'Sauvegarder en cookie ou en base la nouvelle valeur
            If Me.UserId <> -1 Then
                UpdateUserNbResultsPerPage(intPageSize)
            Else
                UpdateCookiePageSize(intPageSize)
            End If

            'Faire un Bind
            Me.PageSize = intPageSize
            PageIndex = 0
            OnRefreshData(New SearchParams(Me.LuceneFilterQuery, GetSortParameter(), Me.PageSize, PageIndex, True))
        End Sub

        Private Sub ctlGroupingField_SelectedItemChanged(ByVal sender As Object, _
                                                 ByVal e As Aricie.ComponentModel.ChangedEventArgs) _
                                                 Handles ctlGroupingField.SelectedItemChanged

            Try
                If ctlGroupingField.Visible Then
                    If e.NewValue IsNot Nothing Then
                        Me.Grouping = DirectCast(e.NewValue, FieldDefinition).Id
                    Else
                        Me.Grouping = ""
                    End If
                    OnRefreshData(New SearchParams(Me.LuceneFilterQuery, GetSortParameter(), Me.PageSize, PageIndex, True))
                End If
            Catch ex As Exception
                ProcessModuleLoadException(Me, ex)
            End Try
        End Sub

#End Region

#Region "Public Functions"
        Public Overrides Sub ConfigGrouping(ByVal fieldName As String)

        End Sub

#End Region

#Region "Privates Functions"

        Private Function GenerateDataSource(ByVal results As IList(Of LuceneSearchResultsInfo), ByVal addGridViewHeader As Boolean, ByVal filterQuery As String, ByVal sortFieldName As String) As DataView
            Dim moduleController As New DotNetNuke.Entities.Modules.ModuleController
            Dim myModule As ModuleInfo = moduleController.GetModule(Me.ModuleID, Me.TabId)
            Dim dt As DataTable

            Dim collectionColumnsDate As New List(Of Integer)
            Dim collectionColumnsHideHeader As New List(Of Integer)
            Dim collectionColumnsHideColumn As New List(Of Integer)
            Dim collectionColumnsLink As New List(Of String)

            Dim matchCollection As MatchCollection = GridViewResultsHelper.GetAllTokens(GetItemTemplate(myModule.ModuleName, Global.Configuration.Templating.Context.TemplateTypes.Grid.ToString(), Me.LuceneResultsSettings))

            'Création de la DataTable
            dt = GridViewResultsHelper.GenerateDataTable(matchCollection, results, collectionColumnsDate, collectionColumnsHideHeader, collectionColumnsHideColumn, collectionColumnsLink, filterQuery, Me.LuceneResultsSettings.EnableHighlighter, Me.LuceneResultsSettings.HighlighterMatchTokenFormat)

            'Création des entêtes de la GridView
            If addGridViewHeader Then
                Me.gridViewAllResults.Columns.Clear()
                Dim i As Integer = 1
                For Each col As DataColumn In dt.Columns
                    If Not collectionColumnsHideColumn.Contains(i) And Not col.ColumnName.Contains(glbWithoutLink) Then
                        Dim bfield As TemplateField = New TemplateField

                        Dim strHeader As String = GridViewResultsHelper.GetHeader(col.ColumnName, GetItemTemplate(myModule.ModuleName, Global.Configuration.Templating.Context.TemplateTypes.Grid.ToString(), Me.LuceneResultsSettings))
                        If strHeader = "" Then
                            strHeader = col.ColumnName
                        End If
                        If collectionColumnsHideHeader.Contains(i) Then
                            strHeader = ""
                        End If
                        Dim ht As New HeaderTemplate(strHeader, col.ColumnName, Me.LuceneResultsSettings.AllowCustomSorting)
                        ht.ID = col.ColumnName

                        AddHandler ht.SortColumn, AddressOf sortColumn

                        bfield.HeaderTemplate = ht

                        If collectionColumnsDate.Contains(i) Then
                            bfield.ItemTemplate = New ItemTemplate(col.ColumnName, True)
                        Else
                            bfield.ItemTemplate = New ItemTemplate(col.ColumnName, False)
                        End If
                        bfield.ItemStyle.CssClass = "LuceneGridView_Col" + col.ColumnName + "_Num" + i.ToString

                        Me.gridViewAllResults.Columns.Add(bfield)
                    End If

                    i += 1
                Next

            End If

            'Permet de Trier les Résultats
            Dim dv As DataView = New DataView(dt)
            Return dv

        End Function

        Public Sub InitLayout()

            ' on détermine la valeur du groupe
            tdGroupingfField.Visible = LuceneResultsSettings.AllowCustomGrouping
            If (Not IsPostBack AndAlso LuceneResultsSettings.AllowCustomGrouping) Then
                Dim GroupingName = EffectiveGrouping.ToLower()
                For i = 0 To ctlGroupingField.AllItems.Count - 1
                    If ctlGroupingField.AllItemsG(i).Id.ToLower = GroupingName Or Me.ctlGroupingField.AllItemsG(i).FriendlyName.ToLower = GroupingName Then
                        ctlGroupingField.DataBind()
                        ctlGroupingField.SelectedIndex = i + 1
                        Exit For
                    End If
                Next
            End If

            tdCustomPageSize.Visible = LuceneResultsSettings.EnablePaging AndAlso LuceneResultsSettings.AllowCustomPageSize
            gridViewAllResults.AllowPaging = LuceneResultsSettings.EnablePaging OrElse LuceneResultsSettings.LimitResults
            gridViewAllResults.PagerSettings.Visible = LuceneResultsSettings.EnablePaging
            If gridViewAllResults.AllowPaging Then
                gridViewAllResults.PageSize = PageSize
            End If
            If tdCustomPageSize.Visible Then
                If PageSize <> -1 AndAlso ddlCustomPageSize.Items.FindByValue(PageSize.ToString()) IsNot Nothing Then
                    Try
                        ddlCustomPageSize.SelectedValue = PageSize.ToString()
                    Catch ex As Exception
                        ' if somebody tweaked the pagesize arg incorrectly, we don't select anything
                        Aricie.Services.ExceptionHelper.LogException(ex)
                    End Try

                Else
                    ddlCustomPageSize.SelectedValue = "Default"
                End If

            End If

        End Sub

        'Tri d'une colonne
        Private Sub sortColumn(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim btn As Button = CType(sender, Button)
            Dim field As String = btn.ID

            Dim sortOrder As String = ""
            If field.Contains("btnDown") Then
                sortOrder = "-"
            End If

            field = field.Replace("btnDown", "").Replace("btnUp", "")
            Sort = sortOrder + field
            OnRefreshData(New SearchParams(Me.LuceneFilterQuery, GetSortParameter(), Me.PageSize, PageIndex, True))
        End Sub

        Public Overrides ReadOnly Property PagerHolder As System.Web.UI.WebControls.PlaceHolder
            Get
                Return phPager
            End Get
        End Property

#End Region

#Region "Tri"

        Protected Property ListSort() As Hashtable
            Get
                Dim toReturn As New Hashtable
                If ViewState("ListSort") IsNot Nothing Then
                    toReturn = DirectCast(ViewState("ListSort"), Hashtable)
                Else
                    Dim moduleController As New DotNetNuke.Entities.Modules.ModuleController
                    Dim myModule As ModuleInfo = moduleController.GetModule(Me.ModuleID, Me.TabId)
                    toReturn = GridViewResultsHelper.GetHashtableSort(GetItemTemplate(myModule.ModuleName, Global.Configuration.Templating.Context.TemplateTypes.Grid.ToString(), Me.LuceneResultsSettings))
                    ViewState("ListSort") = toReturn
                End If
                Return toReturn
            End Get
            Set(ByVal value As Hashtable)
                ViewState("ListSort") = value
            End Set
        End Property

        Protected Overrides Function CustomizeSort(strSortToCustomize As String) As String

            Dim toReturn As String = ""
            If strSortToCustomize <> String.Empty Then
                If ListSort.Count > 0 Then
                    Dim strSortSplit As String() = strSortToCustomize.Split(CChar(","))

                    For Each strSort As String In strSortSplit

                        Dim boolReverse As Boolean = strSort.StartsWith("-")
                        Dim field As String = strSort.TrimStart(CChar("-"))
                        Dim newField As String = ""
                        If ListSort.ContainsKey(field) Then
                            newField = ListSort.Item(field).ToString
                        End If

                        If newField <> String.Empty Then
                            If boolReverse Then
                                toReturn += "-"
                            End If
                            toReturn += newField + ","
                        Else
                            toReturn += strSort + ","
                        End If

                    Next

                Else
                    toReturn = strSortToCustomize
                End If
            End If
            Return toReturn.TrimEnd(CChar(","))
        End Function
#End Region

    End Class
End Namespace